﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DFGK_WMS.Common
{
    /// <summary>
    /// HTTP帮助类
    /// </summary>
    public class HttpClientHelper
    {
        private IHttpClientFactory _httpClientFactory;
        public HttpClientHelper(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }

        /// <summary>
        /// 发起GET异步请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="headers">请求头信息</param>
        /// <param name="timeOut">请求超时时间，单位秒</param>
        /// <returns>返回string</returns>
        public async Task<string> GetAsync(string url, Dictionary<string, string> headers = null, int timeOut = 30)
        {
            using (HttpClient client = _httpClientFactory.CreateClient())
            {
                client.Timeout = TimeSpan.FromSeconds(timeOut);
                if (headers?.Count > 0)
                {
                    foreach (string key in headers.Keys)
                    {
                        client.DefaultRequestHeaders.Add(key, headers[key]);
                    }
                }
                using (HttpResponseMessage response = await client.GetAsync(url))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        string responseString = await response.Content.ReadAsStringAsync();
                        return responseString;
                    }
                    else
                    {
                        return string.Empty;
                    }
                }
            }
        }


        /// <summary>
        /// 发起POST异步请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="body">POST提交的内容</param>
        /// <param name="bodyMediaType">POST内容的媒体类型，如：application/xml、application/json</param>
        /// <param name="responseContentType">HTTP响应上的content-type内容头的值,如：application/xml、application/json、application/text、application/x-www-form-urlencoded等</param>
        /// <param name="headers">请求头信息</param>
        /// <param name="timeOut">请求超时时间，单位秒</param>
        /// <returns>返回string</returns>
        public async Task<string> PostAsync(string url, string body,
            string bodyMediaType = null,
            string responseContentType = null,
            Dictionary<string, string> headers = null,
            int timeOut = 30)
        {
            using (HttpClient client = _httpClientFactory.CreateClient())
            {
                client.Timeout = TimeSpan.FromSeconds(timeOut);
                if (headers?.Count > 0)
                {
                    foreach (string key in headers.Keys)
                    {
                        client.DefaultRequestHeaders.Add(key, headers[key]);
                    }
                }
                StringContent content = new StringContent(body, System.Text.Encoding.UTF8, mediaType: bodyMediaType);
                if (!string.IsNullOrWhiteSpace(responseContentType))
                {
                    content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse(responseContentType);
                }
                using (HttpResponseMessage response = await client.PostAsync(url, content))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        string responseString = await response.Content.ReadAsStringAsync();
                        return responseString;
                    }
                    else
                    {
                        return string.Empty;
                    }
                }
            }
        }

        /// <summary>
        /// 发起PUT异步请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="body">POST提交的内容</param>
        /// <param name="bodyMediaType">POST内容的媒体类型，如：application/xml、application/json</param>
        /// <param name="responseContentType">HTTP响应上的content-type内容头的值,如：application/xml、application/json、application/text、application/x-www-form-urlencoded等</param>
        /// <param name="headers">请求头信息</param>
        /// <param name="timeOut">请求超时时间，单位秒</param>
        /// <returns>返回string</returns>
        public async Task<string> PutAsync(string url, string body,
            string bodyMediaType = null,
            string responseContentType = null,
            Dictionary<string, string> headers = null,
            int timeOut = 30)
        {
            using (HttpClient client = _httpClientFactory.CreateClient())
            {
                client.Timeout = TimeSpan.FromSeconds(timeOut);
                if (headers?.Count > 0)
                {
                    foreach (string key in headers.Keys)
                    {
                        client.DefaultRequestHeaders.Add(key, headers[key]);
                    }
                }
                StringContent content = new StringContent(body, System.Text.Encoding.UTF8, mediaType: bodyMediaType);
                if (!string.IsNullOrWhiteSpace(responseContentType))
                {
                    content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse(responseContentType);
                }
                using (HttpResponseMessage response = await client.PutAsync(url, content))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        string responseString = await response.Content.ReadAsStringAsync();
                        return responseString;
                    }
                    else
                    {
                        return string.Empty;
                    }
                }
            }
        }

        /// <summary>
        /// 发起GET异步请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="headers">请求头信息</param>
        /// <param name="timeOut">请求超时时间，单位秒</param>
        /// <returns>返回string</returns>
        public async Task<string> DeleteAsync(string url, Dictionary<string, string> headers = null, int timeOut = 30)
        {
            using (HttpClient client = _httpClientFactory.CreateClient())
            {
                client.Timeout = TimeSpan.FromSeconds(timeOut);
                if (headers?.Count > 0)
                {
                    foreach (string key in headers.Keys)
                    {
                        client.DefaultRequestHeaders.Add(key, headers[key]);
                    }
                }
                using (HttpResponseMessage response = await client.DeleteAsync(url))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        string responseString = await response.Content.ReadAsStringAsync();
                        return responseString;
                    }
                    else
                    {
                        return string.Empty;
                    }
                }
            }
        }

        /// <summary>
        /// 发起GET异步请求
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="url">请求地址</param>
        /// <param name="headers">请求头信息</param>
        /// <param name="timeOut">请求超时时间，单位秒</param>
        /// <returns>返回T</returns>
        public async Task<T> GetAsync<T>(string url, Dictionary<string, string> headers = null, int timeOut = 30) where T : new()
        {
            string responseString = await GetAsync(url, headers, timeOut);
            if (!string.IsNullOrWhiteSpace(responseString))
            {
                return JsonConvert.DeserializeObject<T>(responseString);
            }
            else
            {
                return default(T);
            }
        }


        /// <summary>
        /// 发起POST异步请求
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="url">请求地址</param>
        /// <param name="body">POST提交的内容</param>
        /// <param name="bodyMediaType">POST内容的媒体类型，如：application/xml、application/json</param>
        /// <param name="responseContentType">HTTP响应上的content-type内容头的值,如：application/xml、application/json、application/text、application/x-www-form-urlencoded等</param>
        /// <param name="headers">请求头信息</param>
        /// <param name="timeOut">请求超时时间，单位秒</param>
        /// <returns>返回T</returns>
        public async Task<T> PostAsync<T>(string url, string body,
            string bodyMediaType = null,
            string responseContentType = null,
            Dictionary<string, string> headers = null,
            int timeOut = 30) where T : new()
        {
            string responseString = await PostAsync(url, body, bodyMediaType, responseContentType, headers, timeOut);
            if (!string.IsNullOrWhiteSpace(responseString))
            {
                return JsonConvert.DeserializeObject<T>(responseString);
            }
            else
            {
                return default(T);
            }
        }

        /// <summary>
        /// 发起PUT异步请求
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="url">请求地址</param>
        /// <param name="body">POST提交的内容</param>
        /// <param name="bodyMediaType">POST内容的媒体类型，如：application/xml、application/json</param>
        /// <param name="responseContentType">HTTP响应上的content-type内容头的值,如：application/xml、application/json、application/text、application/x-www-form-urlencoded等</param>
        /// <param name="headers">请求头信息</param>
        /// <param name="timeOut">请求超时时间，单位秒</param>
        /// <returns>返回T</returns>
        public async Task<T> PutAsync<T>(string url, string body,
            string bodyMediaType = null,
            string responseContentType = null,
            Dictionary<string, string> headers = null,
            int timeOut = 30) where T : new()
        {
            string responseString = await PutAsync(url, body, bodyMediaType, responseContentType, headers, timeOut);
            if (!string.IsNullOrWhiteSpace(responseString))
            {
                return JsonConvert.DeserializeObject<T>(responseString);
            }
            else
            {
                return default(T);
            }
        }

        /// <summary>
        /// 发起DELETE异步请求
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="url">请求地址</param>
        /// <param name="headers">请求头信息</param>
        /// <param name="timeOut">请求超时时间，单位秒</param>
        /// <returns>返回T</returns>
        public async Task<T> DeleteAsync<T>(string url, Dictionary<string, string> headers = null, int timeOut = 30) where T : new()
        {
            string responseString = await DeleteAsync(url, headers, timeOut);
            if (!string.IsNullOrWhiteSpace(responseString))
            {
                return JsonConvert.DeserializeObject<T>(responseString);
            }
            else
            {
                return default(T);
            }
        }
    }
}
